package cn.wsalix.weixin.servlet;

import static cn.wsalix.weixin.util.StrUtil.isNotBlank;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import cn.wsalix.admin.entity.SysUser;
import cn.wsalix.login.form.WxCodeForm;
import cn.wsalix.weixin.entity.WxConfig;
import cn.wsalix.weixin.entity.WxMessage;
import cn.wsalix.weixin.message.req.EventType;
import cn.wsalix.weixin.message.req.ReqType;
import cn.wsalix.weixin.req.entity.ImageReqMsg;
import cn.wsalix.weixin.req.entity.LinkReqMsg;
import cn.wsalix.weixin.req.entity.LocationEvent;
import cn.wsalix.weixin.req.entity.LocationReqMsg;
import cn.wsalix.weixin.req.entity.MenuEvent;
import cn.wsalix.weixin.req.entity.QrCodeEvent;
import cn.wsalix.weixin.req.entity.ScanCodeEvent;
import cn.wsalix.weixin.req.entity.SendPicsInfoEvent;
import cn.wsalix.weixin.req.entity.TextReqMsg;
import cn.wsalix.weixin.req.entity.VoiceReqMsg;
import cn.wsalix.weixin.service.WxService;
import cn.wsalix.weixin.util.Result;
import cn.wsalix.weixin.util.SignUtil;
import cn.wsalix.weixin.util.WxUtils;

import com.thoughtworks.xstream.XStream;

public abstract class WeixinSupport {
	private static final Logger logger = LoggerFactory
			.getLogger(WeixinSupport.class);
	WxUtils wxUtils = new WxUtils();

	@Autowired
	private WxService wxService;

	public String processRequest(WxMessage wxMessage) {
		wxService.saveWxMessage(wxMessage);
		WxConfig wxConfig = wxMessage.getWxConfig();
		String reciveXml = wxUtils.reciveXml(wxMessage.getXmlContent(),
				wxConfig.getWxToken(), wxConfig.getAppId(),
				wxConfig.getAsekey(), wxMessage);// msgSignature, timeStamp,
		logger.info("weixin reciveXml:" + reciveXml); // nonce);
		Map<String, Object> map = wxUtils.buildMap(reciveXml);
		String msgType = (String) map.get("MsgType");
		XStream xStream = new XStream();
		xStream.autodetectAnnotations(true);
		logger.info("msgType：" + msgType);
		if (msgType.equals(ReqType.EVENT)) {
			String eventType = (String) map.get("Event");
			String ticket = (String) map.get("Ticket");
			QrCodeEvent qrCodeEvent = null;
			if (isNotBlank(ticket)) {
				Result<QrCodeEvent> result = wxUtils.parse(reciveXml,
						QrCodeEvent.class);
				if (result.isSuccess()) {
					qrCodeEvent = result.getResult();
					wxService.saveQrCodeEvent(qrCodeEvent);
				}
			}
			if (eventType.equals(EventType.SUBSCRIBE)) {
				logger.info("SUBSCRIBE：" + reciveXml);
				Result<QrCodeEvent> result = wxUtils.parse(reciveXml,
						QrCodeEvent.class);
				if (result.isSuccess()) {
					qrCodeEvent = result.getResult();
					wxService.saveQrCodeEvent(qrCodeEvent);
				}
			} else if (eventType.equals(EventType.UNSUBSCRIBE)) {
				logger.info("UNSUBSCRIBE：" + reciveXml);
				Result<QrCodeEvent> result = wxUtils.parse(reciveXml,
						QrCodeEvent.class);
				if (result.isSuccess()) {
					qrCodeEvent = result.getResult();
					wxService.saveQrCodeEvent(qrCodeEvent);
				}
			} else if (eventType.equals(EventType.CLICK)) {
				MenuEvent event = new MenuEvent("");
			} else if (eventType.equals(EventType.VIEW)) {
				MenuEvent event = new MenuEvent("");

			} else if (eventType.equals(EventType.LOCATION)) {
				double latitude = Double.parseDouble((String) map
						.get("Latitude"));
				double longitude = Double.parseDouble((String) map
						.get("Longitude"));
				double precision = Double.parseDouble((String) map
						.get("Precision"));
				LocationEvent event = new LocationEvent(latitude, longitude,
						precision);

			} else if (EventType.SCANCODEPUSH.equals(eventType)
					|| EventType.SCANCODEWAITMSG.equals(eventType)) {
				String eventKey = (String) map.get("EventKey");
				Map<String, Object> scanCodeInfo = new HashMap<String, Object>();
				String scanType = (String) scanCodeInfo.get("ScanType");
				String scanResult = (String) scanCodeInfo.get("ScanResult");
				ScanCodeEvent event = new ScanCodeEvent(eventKey, scanType,
						scanResult);

			} else if (EventType.PICPHOTOORALBUM.equals(eventType)
					|| EventType.PICSYSPHOTO.equals(eventType)
					|| EventType.PICWEIXIN.equals(eventType)) {
				String eventKey = (String) map.get("EventKey");
				Map<String, Object> sendPicsInfo = new HashMap<String, Object>();
				int count = Integer
						.parseInt((String) sendPicsInfo.get("Count"));
				String picList = (String) sendPicsInfo.get("PicList");
				SendPicsInfoEvent event = new SendPicsInfoEvent(eventKey,
						count, picList);

			}
		} else {
			if (msgType.equals(ReqType.TEXT)) {
				logger.info("TEXT：" + reciveXml);
				xStream.processAnnotations(TextReqMsg.class);
				TextReqMsg textReqMsg = (TextReqMsg) xStream.fromXML(reciveXml);
				wxService.saveTextReqMsg(textReqMsg);
			} else if (msgType.equals(ReqType.IMAGE)) {
				logger.info("IMAGE：" + reciveXml);
				xStream.alias("xml", ImageReqMsg.class);
				ImageReqMsg imageReqMsg = (ImageReqMsg) xStream
						.fromXML(reciveXml);
				wxService.saveImageReqMsg(imageReqMsg);
			} else if (msgType.equals(ReqType.VOICE)) {
				xStream.alias("xml", VoiceReqMsg.class);
				VoiceReqMsg voiceReqMsg = (VoiceReqMsg) xStream
						.fromXML(reciveXml);
				wxService.saveVoiceReqMsg(voiceReqMsg);

			} else if (msgType.equals(ReqType.VIDEO)) {
				Result<VoiceReqMsg> result = wxUtils.parse(reciveXml,
						VoiceReqMsg.class);
				if (result.isSuccess()) {
					VoiceReqMsg qrCodeEvent = result.getResult();
					wxService.saveVoiceReqMsg(qrCodeEvent);
				}

			} else if (msgType.equals(ReqType.LOCATION)) {

				Result<LocationReqMsg> result = wxUtils.parse(reciveXml,
						LocationReqMsg.class);
				if (result.isSuccess()) {
					LocationReqMsg qrCodeEvent = result.getResult();
					wxService.saveLocationReqMsg(qrCodeEvent);
				}
			} else if (msgType.equals(ReqType.LINK)) {
				Result<LinkReqMsg> result = wxUtils.parse(reciveXml,
						LinkReqMsg.class);
				if (result.isSuccess()) {
					LinkReqMsg qrCodeEvent = result.getResult();
					wxService.saveLinkReqMsg(qrCodeEvent);
				}
			}
		}
		return "";
	}

	protected SysUser register(WxConfig wxConfig, WxCodeForm form) {
		return wxService.register(wxConfig, form);
	}

	protected String oauth2(WxConfig wxConfig, String string) {
		return wxService.oauth2(wxConfig, string);
	}

	protected boolean isLegal(HttpServletRequest request, WxConfig wxConfig) {
		String signature = request.getParameter("signature");
		String timestamp = request.getParameter("timestamp");
		String nonce = request.getParameter("nonce");
		return SignUtil.checkSignature(wxConfig.getWxToken(), signature,
				timestamp, nonce);
	}

}